from unittest import TestCase, main

from webtest import TestApp

from clutch.wsgi import make_app_test as make_app

class TestControllers(TestCase):

    def setUp(self):
        self.app = make_app({}, **{
            'use':'egg:Clutch',
            'clutch.app':'TestApplication#main',
            'login_url':'/login'})
        self.tester = TestApp(self.app)

    def testIndex(self):
        res = self.tester.get('/tests/controller/')
        self.assertEqual(res.body, 'Test Index')
        res = self.tester.get('/tests/controller', status=301)
        self.assert_(res.location.endswith('/tests/controller/'))

    def testSimple(self):
        res = self.tester.get('/tests/controller/test1')
        self.assertEqual(res.body, 'Test1')

    def testRedirect(self):
        res = self.tester.get('/tests/controller/test2a', status=302)
        self.assert_(res.location.endswith('/tests/controller/test2b'),
                     res.location)

    def testContinue(self):
        res = self.tester.get('/tests/controller/test3a')
        self.assertEqual(res.body, 'Test3')
                     
    def testRest(self):
        res = self.tester.get('/tests/controller/test5')
        res = self.tester.put('/tests/controller/test5')
        res = self.tester.post('/tests/controller/test5', status=405)
        res = self.tester.delete('/tests/controller/test5', status=405)

    def testParams(self):
        from formencode.variabledecode import variable_encode as enc
        res = self.tester.post('/tests/controller/test6', params=dict(a=5))
        self.assertEqual(res.body, "{'a': '5'}")
        res = self.tester.post('/tests/controller/test6', params=enc(dict(a=5)))
        self.assertEqual(res.body, "{'a': '5'}");
        res = self.tester.post('/tests/controller/test6',
                               params=enc(dict(a=dict(b=5))))
        self.assertEqual(res.body, "{'a': {'b': '5'}}");
        res = self.tester.post('/tests/controller/test6',
                               params=enc(dict(a=[1,2,3])))
        self.assertEqual(res.body, "{'a': ['1', '2', '3']}");
        
    def testValidation(self):
        import formencode
        res = self.tester.post('/tests/controller/test7', params=dict(a=5))
        self.assertEqual(res.body, "{'a': 5}")
        res = self.tester.post('/tests/controller/test7', params=dict(a='foo'))
        self.assert_('Please enter an integer value' in res.body)
        res = self.tester.post('/tests/controller/dfl_invalid/no_invalid/',
                               params=dict(a='foo'))
        self.assert_('exc_info' in res.body)
        self.assertRaises(formencode.Invalid, self.tester.post, 
                          '/tests/controller/no_invalid/',
                          params=dict(a='foo'))

    def testAuthorization(self):
        self.tester.get('/tests/controller/test8',
                        extra_environ=dict(REMOTE_USER='bob'),
                        status=200)
        res = self.tester.get('/tests/controller/test8', status=302)
        self.assert_(res.location.endswith('/login'))
        self.tester.get('/tests/controller/test9',
                        extra_environ=dict(REMOTE_USER='rick'))
        self.tester.get('/tests/controller/test9',
                        extra_environ=dict(REMOTE_USER='bob'),
                        status=403)
        res = self.tester.get('/tests/controller/secure/', status=302)
        self.assert_(res.location.endswith('/login'))
        res = self.tester.get('/tests/controller/secure/inner/', status=302)
        self.assert_(res.location.endswith('/login'))
        self.tester.get('/tests/controller/secure/inner/',
                        extra_environ=dict(REMOTE_USER='bob'),
                        status=200)
        
